﻿using System.IO;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
using Newtonsoft.Json;

namespace Betfair.Api
{
    internal sealed class WebHelper
    {
        private string _applicationName;
        private X509Certificate2 _cert;
        private string _contentType = "application/json";
        private string _data;
        private string _method = "POST";
        private string _sessionToken;
        private string _url;

        public WebHelper Seturl(string url)
        {
            _url = url;
            return this;
        }

        public WebHelper SetMethod(bool isPost = true)
        {
            _method = isPost ? "POST" : "GET";
            return this;
        }

        public WebHelper SetContentType(bool isJson = true)
        {
            _contentType = isJson ? "application/json" : "application/x-www-form-urlencoded";
            return this;
        }

        public WebHelper SetApplicationKey(string applicationName)
        {
            _applicationName = applicationName;
            return this;
        }

        public WebHelper SetCertificate(string path, string password)
        {
            _cert = new X509Certificate2(path, password);
            return this;
        }

        public WebHelper SetDataToPost(string data)
        {
            _data = data;
            return this;
        }

        public WebHelper SetSessionToken(string sessionToken)
        {
            _sessionToken = sessionToken;
            return this;
        }

        public async Task<T> Build<T>()
        {
            var request = (HttpWebRequest) WebRequest.Create(_url);
            request.Method = _method;

            request.ContentType = _contentType;
            request.Accept = "application/json";
            if (!string.IsNullOrWhiteSpace(_applicationName))
                request.Headers.Add("X-Application", _applicationName);

            if (_cert != null)
            {
                request.ClientCertificates.Add(_cert);
            }

            if (!string.IsNullOrWhiteSpace(_sessionToken))
            {
                request.Headers.Add("X-Authentication", _sessionToken);
            }

            request.ContentLength = 0;
            request.Headers.Add(HttpRequestHeader.AcceptCharset, "UTF-8");
            if (!string.IsNullOrWhiteSpace(_data))
            {
                request.ContentLength = _data.Length;
                using (var sw = new StreamWriter(await request.GetRequestStreamAsync()))
                {
                    await sw.WriteAsync(_data);
                    sw.Close();
                }
            }

            var response = (HttpWebResponse) await request.GetResponseAsync();
            Stream stream = response.GetResponseStream();
            if (stream == null)
                return default(T);

            using (var sr = new StreamReader(stream))
            {
                string result = await sr.ReadToEndAsync();
                sr.Close();
                return JsonConvert.DeserializeObject<T>(result);
            }
        }
    }
}